package top.riske.imagebed.utils;

import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * created by vital on 2025/3/5 上午9:12
 */
public class HashUtils {


    /**
     * 计算指定文件的 MD5 值。
     * @param filePath 文件路径
     * @return 文件的 MD5 值
     * @throws IOException 如果文件读取失败
     * @throws NoSuchAlgorithmException 如果算法不可用
     */
    public static String calculateFileMd5(String filePath) throws IOException, NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("MD5");

        try (FileInputStream fis = new FileInputStream(filePath)) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) > 0) {
                digest.update(buffer, 0, len);
            }
        }

        // 将哈希值转换为十六进制字符串
        byte[] hashBytes = digest.digest();
        return bytesToHexString(hashBytes);
    }


    /**
     * 计算 MultipartFile 的 MD5 值，分块读取，以减少内存消耗。
     *
     * @param multipartFile MultipartFile 对象
     * @return 文件的 MD5 值
     * @throws NoSuchAlgorithmException 如果算法不可用
     * @throws IOException 如果文件读取失败
     */
    public static String calculateFileMd5(MultipartFile multipartFile) throws NoSuchAlgorithmException, IOException {
        // 创建 MessageDigest 对象
        MessageDigest digest = MessageDigest.getInstance("MD5");

        // 读取文件内容并计算哈希值
        try (InputStream inputStream = multipartFile.getInputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) > 0) {
                // 更新哈希值
                digest.update(buffer, 0, len);
            }
        }

        // 将哈希值转换为十六进制字符串
        byte[] hashBytes = digest.digest();
        return bytesToHexString(hashBytes);
    }

    /**
     * 将字节数组转换为十六进制字符串
     * @param bytes
     * @return
     */
    private static String bytesToHexString(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

}
